#!/usr/bin/python
# -*- coding:utf-8 -*-

import arrow
from django.conf import settings
from mongoengine.errors import DoesNotExist
from rest_framework.permissions import BasePermission
from rest_framework_simplejwt.authentication import JWTAuthentication
from utilities.errors import Error403
from utilities.djconsole import djconsole
from utilities.redis import captcha_redis as redis_db
from apps.account_manager.display import Tips
from .cache_permission import check_permission, check_api_permission
from .models import Tokens, User
from .account_utils import user_can_authenticate


class CustomPermission(BasePermission):
    def has_permission(self, request, view):
        if hasattr(request, "is_api_token") and getattr(request, "is_api_token"):
            license_info = djconsole.get_license_detail(request)
            if "api" in license_info.get("modules", []):
                return check_api_permission(request)
            return False
        return check_permission(request)


class ApiTokenJWTAuthentication(JWTAuthentication):
    def _token_login(self, request):
        api_token = request.META.get("HTTP_API_TOKEN", "")
        if not api_token:
            return
        if not request.path.startswith('/api/v2/'):
            return
        try:
            token = Tokens.objects.get(token=api_token, is_active=True)
        except DoesNotExist:
            return
        if arrow.get(token.expired_time) < arrow.now():
            return
        user = User.objects.filter(user_id=token.user_id).first()
        request.is_api_token = True
        if user_can_authenticate(user):
            return user, token
        raise Error403(Tips().get(6))

    def get_api_token_user(self, request):
        if getattr(settings, "ENABLE_API_TOKEN", False):
            return self._token_login(request)

    def authenticate(self, request):
        user = self.get_api_token_user(request)
        if not user:
            user = super(ApiTokenJWTAuthentication, self).authenticate(request)
        return user

    def get_raw_token(self, header):
        token = super(ApiTokenJWTAuthentication, self).get_raw_token(header)
        if redis_db.get(f"websoc_black_token_{str(token)}"):
            return None
        return token
